package presentation;

import businessEntities.ColumnsInformationContainer;
import businessEntities.BEFileUtils;
import businessEntities.FilesConfig;
import businessEntities.QueryResultContainer;
import businessEntities.TreeModelWrapper;
import businessLogic.BLConnetionManager;
import businessLogic.BLFileImporter;
import businessLogic.BLInformationFinder;
import businessLogic.BLQueryMenager;
import java.awt.event.WindowEvent;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;
import presentation.entities.DialogCreator;
import presentation.entities.JFrameWrapper;
import presentation.entities.ListSelectionListenerWrapper;
import presentation.entities.QueryTableModel;

public class ListsScreen extends javax.swing.JFrame {

    // <editor-fold defaultstate="collapsed" desc="Netbeans - Generated Code">
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        lists_panel = new javax.swing.JPanel();
        tables_scrollPane = new javax.swing.JScrollPane();
        tables_list = new org.jdesktop.swingx.JXList();
        dbs_scrollPane = new javax.swing.JScrollPane();
        dbs_list = new org.jdesktop.swingx.JXList();
        dbs_label = new javax.swing.JLabel();
        tables_label = new javax.swing.JLabel();
        title_label = new javax.swing.JLabel();
        chooseTable_button = new javax.swing.JButton();
        showTable_button = new javax.swing.JButton();
        mainError_label = new javax.swing.JLabel();
        menuBar = new javax.swing.JMenuBar();
        navigation_menu = new javax.swing.JMenu();
        back_menuItem = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JPopupMenu.Separator();
        close_menuItem = new javax.swing.JMenuItem();
        tools_menu = new javax.swing.JMenu();
        importTree_menuItem = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("Databases and Tables");
        setIconImage(Toolkit.getDefaultToolkit().getImage(PresentationConfig.framesIconPath));
        setName("chooseTable_frame"); // NOI18N
        setResizable(false);

        lists_panel.setPreferredSize(new java.awt.Dimension(680, 400));

        tables_scrollPane.setPreferredSize(new java.awt.Dimension(320, 320));

        tables_list.setFont(new java.awt.Font("Microsoft YaHei", 1, 14)); // NOI18N
        tables_list.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        tables_scrollPane.setViewportView(tables_list);

        dbs_scrollPane.setPreferredSize(new java.awt.Dimension(320, 320));

        dbs_list.setFont(new java.awt.Font("Microsoft YaHei", 1, 16)); // NOI18N
        dbs_list.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        dbs_list.setName(""); // NOI18N
        dbs_scrollPane.setViewportView(dbs_list);
        dbs_list.getAccessibleContext().setAccessibleName("");
        dbs_list.getAccessibleContext().setAccessibleDescription("");

        dbs_label.setFont(new java.awt.Font("Segoe Print", 1, 24));
        dbs_label.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        dbs_label.setText("Databases");

        tables_label.setFont(new java.awt.Font("Segoe Print", 1, 24));
        tables_label.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        tables_label.setText("Tables");

        title_label.setFont(new java.awt.Font("Arial Rounded MT Bold", 1, 24));
        title_label.setForeground(new java.awt.Color(0, 0, 255));
        title_label.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        title_label.setText("Existing Databases and Tables On The Server");

        chooseTable_button.setFont(new java.awt.Font("Segoe Print", 1, 18));
        chooseTable_button.setText("Filter Selected Table");
        chooseTable_button.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        chooseTable_button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                chooseTable_buttonActionPerformed(evt);
            }
        });

        showTable_button.setFont(new java.awt.Font("Segoe Print", 1, 18));
        showTable_button.setText("Show Selected Table");
        showTable_button.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        showTable_button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                showTable_buttonActionPerformed(evt);
            }
        });

        mainError_label.setFont(new java.awt.Font("Tahoma", 1, 12));
        mainError_label.setForeground(new java.awt.Color(255, 0, 0));

        org.jdesktop.layout.GroupLayout lists_panelLayout = new org.jdesktop.layout.GroupLayout(lists_panel);
        lists_panel.setLayout(lists_panelLayout);
        lists_panelLayout.setHorizontalGroup(
            lists_panelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, lists_panelLayout.createSequentialGroup()
                .addContainerGap()
                .add(lists_panelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(title_label, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 857, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.LEADING, mainError_label, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 857, Short.MAX_VALUE)
                    .add(lists_panelLayout.createSequentialGroup()
                        .add(lists_panelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(chooseTable_button, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 393, Short.MAX_VALUE)
                            .add(dbs_label, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 393, Short.MAX_VALUE)
                            .add(dbs_scrollPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 393, Short.MAX_VALUE))
                        .add(70, 70, 70)
                        .add(lists_panelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                            .add(showTable_button, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 394, Short.MAX_VALUE)
                            .add(tables_scrollPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 394, Short.MAX_VALUE)
                            .add(org.jdesktop.layout.GroupLayout.LEADING, tables_label, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 394, Short.MAX_VALUE))))
                .addContainerGap())
        );
        lists_panelLayout.setVerticalGroup(
            lists_panelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(lists_panelLayout.createSequentialGroup()
                .add(title_label, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 39, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(lists_panelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(dbs_label)
                    .add(tables_label))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(lists_panelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(dbs_scrollPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 344, Short.MAX_VALUE)
                    .add(tables_scrollPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 344, Short.MAX_VALUE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(lists_panelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(showTable_button, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 43, Short.MAX_VALUE)
                    .add(chooseTable_button, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 43, Short.MAX_VALUE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                .add(mainError_label, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 43, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        navigation_menu.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/navigation-icon.png"))); // NOI18N
        navigation_menu.setText("Navigation");
        navigation_menu.setFont(new java.awt.Font("Arial Rounded MT Bold", 1, 12));

        back_menuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_A, java.awt.event.InputEvent.SHIFT_MASK));
        back_menuItem.setFont(new java.awt.Font("Arial Rounded MT Bold", 0, 12));
        back_menuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/database-connection-icon.png"))); // NOI18N
        back_menuItem.setText("Back to login screen");
        back_menuItem.setToolTipText("Disconnect  from the server and go back to login screen ");
        back_menuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                back_menuItemActionPerformed(evt);
            }
        });
        navigation_menu.add(back_menuItem);
        navigation_menu.add(jSeparator1);

        close_menuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.event.InputEvent.SHIFT_MASK));
        close_menuItem.setFont(new java.awt.Font("Arial Rounded MT Bold", 0, 12));
        close_menuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/shutdown-icon.png"))); // NOI18N
        close_menuItem.setText("Close");
        close_menuItem.setToolTipText("Disconnect from the server and close the program");
        close_menuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                close_menuItemActionPerformed(evt);
            }
        });
        navigation_menu.add(close_menuItem);

        menuBar.add(navigation_menu);

        tools_menu.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/tools-icon.png"))); // NOI18N
        tools_menu.setText("Tools");
        tools_menu.setFont(new java.awt.Font("Arial Rounded MT Bold", 1, 12));

        importTree_menuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_I, java.awt.event.InputEvent.SHIFT_MASK));
        importTree_menuItem.setFont(new java.awt.Font("Arial Rounded MT Bold", 0, 12));
        importTree_menuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/xml_icon.png"))); // NOI18N
        importTree_menuItem.setText("Import Tree from XML");
        importTree_menuItem.setToolTipText("Import Tree from XML file");
        importTree_menuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                importTree_menuItemActionPerformed(evt);
            }
        });
        tools_menu.add(importTree_menuItem);

        menuBar.add(tools_menu);

        setJMenuBar(menuBar);

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(lists_panel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 877, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .add(lists_panel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 553, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

private void showTable_buttonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showTable_buttonActionPerformed
    mainError_label.setText("");
    showTable();
}//GEN-LAST:event_showTable_buttonActionPerformed

private void back_menuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_back_menuItemActionPerformed
    if(DialogCreator.backToLoginDialog(this) == 0){
        setVisible(false);
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new ConnectionScreen().setVisible(true);
            }});
        closeConnectionOnClose = true;
        userClickOnExit = false;
        this.dispose();
    }
}//GEN-LAST:event_back_menuItemActionPerformed

private void close_menuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_close_menuItemActionPerformed
    if(DialogCreator.closeProgramDialog(this) == 0){
        setVisible(false);
        closeConnectionOnClose = true;
        userClickOnExit = false;
        this.dispose();
    }
}//GEN-LAST:event_close_menuItemActionPerformed

private void chooseTable_buttonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chooseTable_buttonActionPerformed
    mainError_label.setText("");
    goToNextScreen();
}//GEN-LAST:event_chooseTable_buttonActionPerformed

    private void importTree_menuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_importTree_menuItemActionPerformed
        
        File workspaceDir = new File(FilesConfig.WORKSPACE_DIR_PATH);
        JFileChooser fileChooser;
        if(workspaceDir.isDirectory()){
            fileChooser = new JFileChooser(workspaceDir);
        }
        else {
            fileChooser = new JFileChooser(System.getProperty("user.home"));
        }

        fileChooser.setFileFilter(new FileFilter() {

            @Override
            public boolean accept(File f) {
                if (f.isDirectory()) {
                    return true;
                }
                if (BEFileUtils.getFileExtention(f.getPath()).equals("xml")) {
                    return true;
                }
                return false;
            }

            @Override
            public String getDescription() {
                return ".xml";
            }
        });

        int returnVal = fileChooser.showOpenDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fileChooser.getSelectedFile();
            BLFileImporter importer = new BLFileImporter();
            TreeModelWrapper modelWrapper = importer.importTreeFromXML(file);
            if (modelWrapper != null) {
                String dbName = modelWrapper.getDatabaseName();
                String table = modelWrapper.getTableName();
                if (!informationMap.containsKey(dbName)) {
                    DialogCreator.showMessage(this, "Tree Import Failed", "Tree Import Failed.\nDatabase : " + dbName + " does not exist.", JOptionPane.ERROR_MESSAGE);
                    return;
                } else {
                    List<String> tables = informationMap.get(dbName);
                    if (!tables.contains(table)) {
                        DialogCreator.showMessage(this, "Tree Import Failed", "Tree import failed.\nTable : " + table + " does not exist.", JOptionPane.ERROR_MESSAGE);
                        return;
                    } else {
                        BLInformationFinder columnsFinder = new BLInformationFinder();
                        ColumnsInformationContainer columnsData = columnsFinder.getColumns((String) dbName, (String) table);
                        if (columnsData != null) {
                             this.setVisible(false);
                                TableFilteringScreen dbFileDbFilterScreen = new TableFilteringScreen((String) dbName, (String) table, columnsData,modelWrapper.getTreeModel());
                                JFrameWrapper wrapper = new JFrameWrapper(dbFileDbFilterScreen);
                                javax.swing.SwingUtilities.invokeLater(wrapper);

                                this.closeConnectionOnClose = false;
                                this.userClickOnExit = false;
                                this.dispose();
                        } else {
                            mainError_label.setText("* Could not retrieve information about the columns in the table.");
                        }
                    }
                }
            } else {
                DialogCreator.showMessage(this, "Tree Import Failed.", "Tree Import Failed.\nFor more information please refer 'runtime.log'.", JOptionPane.ERROR_MESSAGE);
            }
        }
    }//GEN-LAST:event_importTree_menuItemActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem back_menuItem;
    private javax.swing.JButton chooseTable_button;
    private javax.swing.JMenuItem close_menuItem;
    private javax.swing.JLabel dbs_label;
    private javax.swing.JList dbs_list;
    private javax.swing.JScrollPane dbs_scrollPane;
    private javax.swing.JMenuItem importTree_menuItem;
    private javax.swing.JPopupMenu.Separator jSeparator1;
    private javax.swing.JPanel lists_panel;
    private javax.swing.JLabel mainError_label;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JMenu navigation_menu;
    private javax.swing.JButton showTable_button;
    private javax.swing.JLabel tables_label;
    private javax.swing.JList tables_list;
    private javax.swing.JScrollPane tables_scrollPane;
    private javax.swing.JLabel title_label;
    private javax.swing.JMenu tools_menu;
    // End of variables declaration//GEN-END:variables
    Map<String, List<String>> informationMap = null;
    private boolean closeConnectionOnClose = true;
    private boolean userClickOnExit = true;

    /** Constructor */
    public ListsScreen() {

        initComponents();

        // sets the frame location to the center of the screen
        setLocationRelativeTo(null);

        initWindowsListner();

        listsBinding();

        createSelectionHandler();

    }

    private void listsBinding() {
        BLInformationFinder infoFinder = new BLInformationFinder();
        informationMap = infoFinder.getDbInformation();

        if (informationMap != null) {
            //sort the keys in informationMap and bind them to dbs_list
            Object[] databases = informationMap.keySet().toArray();
            Arrays.sort(databases);
            this.dbs_list.setListData(databases);
        } else {
            this.mainError_label.setText("* Could not retrieve information about the Databases on the server.");
        }
    }

    private void createSelectionHandler() {
        ListSelectionListenerWrapper selectionListner = new ListSelectionListenerWrapper(dbs_list, tables_list, informationMap);
        dbs_list.addListSelectionListener(selectionListner);
    }

    private void showTable() {
        Object dbName = dbs_list.getSelectedValue();
        Object tableName = tables_list.getSelectedValue();

        if (dbName == null || tableName == null) {
            this.mainError_label.setText("* You have to select database and table.");
            return;
        }

        BLQueryMenager dbQuery = new BLQueryMenager();
        QueryResultContainer dataContainer = dbQuery.getWholeTable((String) (dbName), (String) (tableName));
        if (dataContainer == null) {
            this.mainError_label.setText("* Could not retrieve data from '" + dbName + "' Database.");
            return;
        }

        String tableFrameTitle = "Database : \"" + dbName + "\", Table : \"" + tableName + "\".";
        QueryTableModel tableModel = new QueryTableModel(dataContainer);
        TableFrame tableFrame = new TableFrame(tableFrameTitle, tableModel);
        JFrameWrapper tableFrameWrapper = new JFrameWrapper(tableFrame);
        javax.swing.SwingUtilities.invokeLater(tableFrameWrapper);
    }

    private void goToNextScreen() {
        Object dbName = dbs_list.getSelectedValue();
        Object tableName = tables_list.getSelectedValue();
        if (dbName == null || tableName == null) {
            this.mainError_label.setText("* You have to select database and table.");
            return;
        }

        BLInformationFinder columnsFinder = new BLInformationFinder();
        ColumnsInformationContainer columnsData = columnsFinder.getColumns((String) dbName, (String) tableName);
        if (columnsData != null) {
            this.setVisible(false);
            TableFilteringScreen dbFileDbFilterScreen = new TableFilteringScreen((String) dbName, (String) tableName, columnsData,null);
            JFrameWrapper wrapper = new JFrameWrapper(dbFileDbFilterScreen);
            javax.swing.SwingUtilities.invokeLater(wrapper);

            this.closeConnectionOnClose = false;
            this.userClickOnExit = false;
            this.dispose();
        } else {
            mainError_label.setText("* Could not retrieve information about the columns in the selected table.");
        }
    }

    private void initWindowsListner() {
        this.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosed(WindowEvent e) {
                if (closeConnectionOnClose) {
                    BLConnetionManager.closeConnection();
                }
            }

            @Override
            public void windowClosing(WindowEvent e) {

                if (userClickOnExit) {
                    if (DialogCreator.closeProgramDialog((JFrame) e.getSource()) == 0) {
                        setVisible(false);
                        BLConnetionManager.closeConnection();
                        dispose();
                    }
                } else if (closeConnectionOnClose) {
                    BLConnetionManager.closeConnection();
                }

            }
        });
    }
    
}
